package com.innovation.ic.im.end.web.controller.im_erp9;

import com.innovation.ic.b1b.framework.util.StringUtils;
import com.innovation.ic.im.end.base.model.im_erp9.UserGroupMessage;
import com.innovation.ic.im.end.base.pojo.ApiResult;
import com.innovation.ic.im.end.base.pojo.ServiceResult;
import com.innovation.ic.im.end.base.pojo.constant.MessageType;
import com.innovation.ic.im.end.base.pojo.constant.RabbitMqExchangeMap;
import com.innovation.ic.im.end.base.pojo.im_erp9.AccountGroupLastContactPojo;
import com.innovation.ic.im.end.base.pojo.im_erp9.ScAccountFindLastContactResultPojo;
import com.innovation.ic.im.end.base.value.config.RabbitMqParamConfig;
import com.innovation.ic.im.end.base.vo.im_erp9.UserGroupVo;
import com.innovation.ic.im.end.web.controller.AbstractController;
import com.innovation.ic.im.end.web.endpoint.UserGroupEndpoint;
import com.innovation.ic.im.end.web.thread.SaveUserGroupNameUpdateMessageThread;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 用户自定义群组API
 */
@Api(value = "用户自定义群组API", tags = "UserGroupController")
@RestController
@RequestMapping("/api/v1/userGroup")
@DefaultProperties(defaultFallback = "defaultFallback")
public class UserGroupController extends AbstractController {
    private static final Logger log = LoggerFactory.getLogger(UserGroupController.class);

    @Resource
    private RabbitMqParamConfig rabbitMqParamConfig;

    /**
     * 创建用户自定义群组，并添加账号和群组的关系
     * @return
     */
    @HystrixCommand
    @ApiOperation(value = "创建用户自定义群组，并添加账号和群组的关系")
    @ApiImplicitParam(name = "userGroupVo", value = "用户自定义群组vo类", required = true, dataType = "UserGroupVo")
    @RequestMapping(value = "/create", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> create(@RequestBody UserGroupVo userGroupVo, HttpServletRequest request, HttpServletResponse response) {
        if (null == userGroupVo || !StringUtils.validateParameter(userGroupVo.getName())
                || null == userGroupVo.getNewMemberAccountIdList()
                || userGroupVo.getNewMemberAccountIdList().size() == 0) {
            String message = "调用接口【/api/v1/userGroup/create时】，参数name、newMemberAccountIdString不能为空";
            log.warn(message);
            ApiResult<Integer> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        if(userGroupVo.getNewMemberAccountIdList().size() < 3){
            String message = "调用接口【/api/v1/userGroup/create时】，参数newMemberAccountIdList中成员数量至少为3个";
            log.warn(message);
            ApiResult<Integer> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        ServiceResult<Integer> serviceResult = userGroupService.saveUserGroupAndRefUserGroupAccount(userGroupVo.getName(), userGroupVo.getNewMemberAccountIdList());

        ApiResult<Integer> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setResult(serviceResult.getResult());
        apiResult.setMessage(ServiceResult.INSERT_SUCCESS);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 根据自定义群组Id获取自定义群组中在线人数
     * @param userGroupId 自定义群组id
     * @param request 请求体
     * @param response 返回体
     * @return 群组中在线人数
     */
    @HystrixCommand
    @ApiOperation(value = "根据自定义群组Id获取自定义群组中在线人数")
    @ApiImplicitParam(name = "userGroupId", value = "自定义群组id", required = true, dataType = "String")
    @RequestMapping(value = "/userNumberOnline/{userGroupId}", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> userNumberOnline(@PathVariable("userGroupId") String userGroupId, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(userGroupId)) {
            String message = "调用接口【/api/v1/userGroup/userNumberOnline/{userGroupId}时，参数userGroupId不能为空";
            log.warn(message);
            ApiResult<Long> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 根据自定义群组Id获取自定义群组中在线人数
        ServiceResult<Long> serviceResult = userGroupService.getUserNumberOnline(userGroupId);

        ApiResult<Long> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setResult(serviceResult.getResult());
        apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 获取近期的联系人(包含一对一、默认群组和自定义群组数据)。按置顶顺序降序排列，按最后聊天时间降序排列。显示未读消息数量
     * @return 返回近期的联系人数据
     */
    @HystrixCommand
    @ApiOperation(value = "获取近期的联系人(包含一对一、默认群组和自定义群组数据)。按置顶顺序降序排列，按最后聊天时间降序排列。显示未读消息数量")
    @ApiImplicitParam(name = "account", value = "账号", required = true, dataType = "String")
    @RequestMapping(value = "/current/{account}", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> current(@PathVariable("account") String account, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(account)) {
            String message = "调用接口【/api/v1/userGroup/current/{account}时，参数account不能为空";
            log.warn(message);
            ApiResult<List<AccountGroupLastContactPojo>> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        ServiceResult<List<AccountGroupLastContactPojo>> serviceResult = userGroupService.findRedisLastContact(account);

        ApiResult<List<AccountGroupLastContactPojo>> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setResult(serviceResult.getResult());
        apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 获取供应商协同账号的近期联系人。按置顶顺序降序排列，按最后聊天时间降序排列。显示未读消息数量
     * @param account 账号
     * @param request request
     * @param response response
     * @return 返回查询结果
     */
    @HystrixCommand
    @ApiOperation(value = "获取供应商协同账号的近期联系人。按置顶顺序降序排列，按最后聊天时间降序排列。显示未读消息数量")
    @ApiImplicitParam(name = "account", value = "账号", required = true, dataType = "String")
    @RequestMapping(value = "/getScRecentContact/{account}", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> getScRecentContact(@PathVariable("account") String account, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(account)) {
            String message = "调用接口【/api/v1/userGroup/getScRecentContact/{account}时，参数account不能为空";
            log.warn(message);
            ApiResult<List<AccountGroupLastContactPojo>> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 从redis中获取供应商协同账号的近期联系人
        ServiceResult<List<ScAccountFindLastContactResultPojo>> serviceResult = userGroupService.findRedisScRecentContact(account);

        ApiResult<List<ScAccountFindLastContactResultPojo>> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setResult(serviceResult.getResult());
        apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 根据群组id修改用户自定义群组名称
     * @param userGroupVo 自定义群组内容
     * @param request 请求内容
     * @param response 返回内容
     * @return 返回结果
     */
    @HystrixCommand
    @ApiOperation(value = "根据群组id修改用户自定义群组名称")
    @ApiImplicitParam(name = "userGroupVo", value = "用户自定义群组vo对象", required = true, dataType = "UserGroupVo")
    @RequestMapping(value = "/update", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult> update(@RequestBody UserGroupVo userGroupVo,
                                            HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(userGroupVo.getId()) || !StringUtils.validateParameter(userGroupVo.getName())|| userGroupVo.getMembership() == null
            || !StringUtils.validateParameter(userGroupVo.getUpdateUserGroupNameRealName()) || !StringUtils.validateParameter(userGroupVo.getUpdateUserGroupNameAccount())) {
            String message = "调用接口【/api/v1/userGroup/update时，参数id,name,membership,updateUserGroupNameAccount,updateUserGroupNameRealName不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }
        // 更新自定义群组名称
        ServiceResult<Integer> result = userGroupService.updateUserGroup(userGroupVo);

        if(result.getResult() != null && result.getResult() > 0){
            // 记录修改群组名称消息并推送给群里的所有人
            saveUpdateUserGroupNameMsgAndSendToAllUser(userGroupVo);
        }

        ApiResult<Boolean> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(ServiceResult.UPDATE_SUCCESS);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 记录修改群组名称消息并推送给群里的所有人
     * @param userGroupVo 自定义群组内容
     */
    private void saveUpdateUserGroupNameMsgAndSendToAllUser(UserGroupVo userGroupVo) {
        Map<String, Set<UserGroupEndpoint>> onlineUserGroupMap = UserGroupEndpoint.onlineUserGroupMap;

        // 保存自定义群组消息
        UserGroupMessage userGroupMessage = new UserGroupMessage();
        String content = userGroupVo.getUpdateUserGroupNameRealName() + " 修改了群名为 " + userGroupVo.getName();
        userGroupMessage.setContent(content);
        userGroupMessage.setFromUserAccount(userGroupVo.getUpdateUserGroupNameAccount());
        userGroupMessage.setFromUserRealName(userGroupVo.getUpdateUserGroupNameRealName());
        userGroupMessage.setType(MessageType.UPDATE_USER_GROUP_NAME_SYS_MSG);
        userGroupMessage.setUserGroupId(Integer.valueOf(userGroupVo.getId()));
        SaveUserGroupNameUpdateMessageThread saveUserGroupNameUpdateMessageThread = new SaveUserGroupNameUpdateMessageThread(userGroupMessage,
                rabbitMqParamConfig.getExchange().get(RabbitMqExchangeMap.CURRENT_EXCHANGE), onlineUserGroupMap);
        threadPoolManager.execute(saveUserGroupNameUpdateMessageThread);
    }
}